﻿//  Copyright (c) 2010 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CookComputing.XmlRpc;
using DNA.OpenAPI.Blogging;
using DNA.Mvc.Security;
using DNA.Mvc.Publishing;

namespace DNA.Mvc.Publishing.Services
{
    public class WeblogService : XmlRpcService, IMetaWeblog, IBlogger, IWordPress, IMovableType
    {
        private IMembershipService _membership;
        private IPubService srv;

        public WeblogService(IMembershipService membership, IPubService service)
        {
            _membership = membership;
            srv = service;
        }

        #region Helper methods

        private bool ValidateUser(string username, string password)
        {
            return _membership.ValidateUser(username, password);
        }

        private CategoryInfo PopuplateCategoryInfo(Category category, int uncategorized)
        {
            var cat = new CategoryWrapper(category);

            return new CategoryInfo()
            {
                categoryId = cat.ID.ToString(),
                categoryName = uncategorized != cat.ID ? cat.Title : "Uncategorized",
                parentId = cat.ParentID,
                description = string.IsNullOrEmpty(cat.Description) ? cat.Title : cat.Description,
                title = cat.Title,
                htmlUrl = cat.PermaLink, // cat.GetPermalinkUrl().ToString(),
                rssUrl = cat.RssUrl
            };
        }

        private Post PopuplatePost(Article art)
        {
            var date = art.Posted;
            var article = new ArticleWrapper(art);
            var categories = new List<string>();
            categories.Add(article.Category.Title);
            if (!string.IsNullOrEmpty(article.Categories))
            {
                var categoriesInPost = srv.GetCategories(article.Categories.Split(new char[] { ',' }).Select(f => int.Parse(f)).ToArray());
                //_pubContext.Categories.Includes(article.Categories.Split(new char[] { ',' }).Select(f => int.Parse(f)).ToArray());
                if (categoriesInPost.Count() > 0)
                    categories.AddRange(categoriesInPost.Select(c => c.Title).ToArray());
            }

            var post = new Post()
            {
                postid = article.ID.ToString(),
                dateCreated = article.Posted,
                description = article.Body,
                title = article.Title,
                userid = article.UserName,
                permalink = article.PermaLink,
                link = article.PermaLink,
                categories = categories.ToArray(),
                publish = article.IsPublished,
                dna_parent_postid = article.ParentID != 0 ? article.ParentID.ToString() : "",
                wp_slug = string.IsNullOrEmpty(article.Slug) ? TextUtility.Slug(article.Title) : article.Slug,
                wp_author = article.UserName,

                mt_keywords = article.Tags,
                mt_excerpt = article.Summary,
                //mt_tb_ping_urls = string.IsNullOrEmpty(article.SendTrackbackUrls) ? (new string[] { }) : article.SendTrackbackUrls.Split(new char[] { ',' }),
                mt_allow_pings = article.AllowPingback ? 1 : 0,
                mt_allow_comments = article.AllowComments ? 1 : 0,
                mt_tags = article.Tags
            };
            return post;
        }

        //private static Page PopuplatePage(WebPage webPage)
        //{
        //    var widgets = webPage.GetWidgets();
        //    var widget = widgets.FirstOrDefault(w => ((w.Action == "SimpleHtml") && (w.Controller == "Widget")));
        //    string desc = "";
        //    if (widget != null)
        //    {
        //        var dict = widget.ReadUserPreferences();
        //        if (dict.Keys.Contains("Text"))
        //            desc = dict["Text"] as string;
        //    }

        //    var user = System.Web.Profile.ProfileBase.Create(webPage.Owner);
        //    user.Initialize(webPage.Owner, true);
        //    var parentPage = webPage.GetParent();
        //    var basePath = WebSite.Open().GetFullUrl();
        //    var page = new Page()
        //    {
        //        page_id = webPage.ID,
        //        title = webPage.Title,
        //        description = desc,
        //        excerpt = string.IsNullOrEmpty(webPage.Description) ? webPage.Title : webPage.Description,
        //        dateCreated = webPage.Created,
        //        page_status = "Publish",
        //        mt_allow_comments = 0,
        //        mt_keywords = "",
        //        mt_allow_pings = 0,
        //        wp_author_id = 0,
        //        categories = new string[] { },
        //        permaLink = basePath + webPage.ClientUrl,
        //        date_created_gmt = webPage.Created.ToUniversalTime(),
        //        wp_page_template = webPage.ViewName,
        //        wp_page_order = webPage.Pos,
        //        wp_page_parent_id = webPage.ParentID,
        //        wp_author = webPage.Owner,
        //        wp_author_display_name = user.GetPropertyValue("DisplayName") as string,
        //        wp_page_parent_title = parentPage != null ? parentPage.Title : "",
        //        wp_slug = TextUtility.Slug(webPage.Title),
        //        custom_fields = (new List<CustomField>()).ToArray(),
        //        link = basePath + webPage.ClientUrl
        //    };
        //    return page;
        //}

        private void BindArticle(Post post, Article article)
        {
            article.Title = post.title;
            article.Posted = post.dateCreated != null ? (DateTime)post.dateCreated : DateTime.Now;
            article.AllowComments = post.mt_allow_comments == 0 ? false : true;
            article.AllowPingback = post.mt_allow_pings == 0 ? false : true;
            article.UserName = post.userid;
            article.Body = post.description;
            article.Slug = string.IsNullOrEmpty(post.wp_slug) ? TextUtility.Slug(article.Title) : TextUtility.Slug(post.wp_slug);
            article.IsAppoved = true;

            if (!string.IsNullOrEmpty(post.dna_parent_postid))
                article.ParentID = int.Parse(post.dna_parent_postid);

            if ((post.mt_tb_ping_urls != null) && (post.mt_tb_ping_urls.Length > 0))
            {
                var _urls = new List<string>();
                foreach (var _url in post.mt_tb_ping_urls)
                {
                    if (_url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                        _urls.Add(_url);
                }

                if (_urls.Count > 0)
                    article.SendTrackbackUrls = string.Join(" ", _urls.ToArray());
            }

            if (!string.IsNullOrEmpty(post.mt_excerpt))
                article.Summary = post.mt_excerpt;

            if (!string.IsNullOrEmpty(post.mt_keywords))
                article.Tags = post.mt_keywords;

            article.LastModified = DateTime.Now;
        }

        #endregion

        #region IMetaWeblog members

        string IMetaWeblog.NewPost(string blogid, string username, string password, Post content, bool publish)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(blogid);
                var article = new Article()
                {
                    ContentFormat = (int)TextFormats.Xhtml,
                    IsPublished = publish
                };
                BindArticle(content, article);

                if (string.IsNullOrEmpty(article.UserName))
                    article.UserName = username;

                if ((content.categories != null) && (content.categories.Length > 0))
                    srv.NewPost(blogid, article, content.categories);
                else
                    srv.NewPost(article);

                return article.ID.ToString();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        bool IMetaWeblog.EditPost(string postid, string username, string password, Post content, bool publish)
        {
            if (ValidateUser(username, password))
            {
                bool result = false;
                int _id = int.Parse(postid);
                //var blog = OpenBlog(username);
                var article = srv.GetPost(_id);
                // blog.GetPost(postid);

                if (!article.IsOwner(username))
                    throw new XmlRpcFaultException(500, "Your are not this article author!");

                if (article != null)
                {
                    BindArticle(content, article);

                    if (string.IsNullOrEmpty(article.Language))
                        article.Language = "en-US";
                    //web.DefaultLanguage;

                    article.IsPublished = publish;
                    article.UserName = username;
                    srv.EditPost(article);

                    //  article.Update();
                    result = true;
                }
                return result;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        Post IMetaWeblog.GetPost(string postid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                var _id = int.Parse(postid);
                //var blog = OpenBlog(username);
                var art = srv.GetPost(_id);// blog.GetPost(postid);
                if ((art != null) && (art.UserName == username))
                {
                    Post post = PopuplatePost(art);
                    return post;
                }
                throw XmlRpcExcpetionFactory.PostNotFound();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        CategoryInfo[] IMetaWeblog.GetCategories(string blogid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                List<CategoryInfo> categoryInfos = new List<CategoryInfo>();
                int topId = srv.FindCategory(blogid).ID;
                var cats = srv.GetCategories(blogid);

                foreach (var cat in cats)
                {
                    categoryInfos.Add(PopuplateCategoryInfo(cat, topId));
                }

                return categoryInfos.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }


        Post[] IMetaWeblog.GetRecentPosts(string blogid, string username, string password, int numberOfPosts)
        {
            if (ValidateUser(username, password))
            {
                List<Post> posts = new List<Post>();
                //var blog = OpenBlog(blogid);

                var cat = srv.FindCategory(blogid);
                var total = 0;
                var arts = srv.GetRecentPosts(blogid, 0, numberOfPosts, out total);

                //arts.AsParallel().ForAll(a => { posts.Add(PopuplatePost(a)); });

                foreach (var a in arts)
                    posts.Add(PopuplatePost(a));
                return posts.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        MediaObjectInfo IMetaWeblog.NewMediaObject(string blogid, string username, string password, MediaObject mediaObject)
        {
            if (ValidateUser(username, password))
            {
                //var web = WebSite.Open(blogid);
                //var blog = OpenBlog(blogid);

                MediaObjectInfo objectInfo = new MediaObjectInfo();
                if (string.IsNullOrEmpty(mediaObject.name))
                    throw new XmlRpcFaultException(440, "File name requried.");

                string fileName = DateTime.Now.ToString("yyMMdd-HHmmss") + "-" + System.IO.Path.GetFileNameWithoutExtension(mediaObject.name.Replace("?", "0"));
                string extension = System.IO.Path.GetExtension(mediaObject.name);
                fileName = TextUtility.Slug(fileName) + extension;

                var url = srv.SaveMedia(blogid, fileName, mediaObject.bits, mediaObject.type);

                objectInfo.url = url.ToString();
                objectInfo.file = fileName;
                objectInfo.type = FileUtility.GetContentType(fileName);

                return objectInfo;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        #endregion

        #region IBlogger members

        bool IBlogger.DeletePost(string key, string postid, string username, string password, bool publish)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(username);
                var _id = int.Parse(postid);
                var article = srv.GetPost(_id);

                // blog.GetPost(postid);

                if (article == null)
                    throw XmlRpcExcpetionFactory.PostNotFound();

                if (!article.IsOwner(username))
                    throw new XmlRpcFaultException(500, "Your are not this article author!");

                srv.DeletePost(_id);

                return true;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        BlogInfo[] IBlogger.GetUsersBlogs(string key, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                List<BlogInfo> infoList = new List<BlogInfo>();
                var blogs = srv.GetUserBlogs(username);

                foreach (var blog in blogs)
                {
                    if (blog.Owner.Equals(username))
                    {
                        infoList.Add(new BlogInfo()
                        {
                            blogid = blog.Name,
                            blogName = blog.Title,
                            url = blog.Url,
                            isAdmin = true,
                            xmlrpc = blog.Url + ("/xmlrpc.metaweblog")
                        });
                    }
                }

                //var w = WebSite.Open(username);
                //var root = WebSite.Open();

                //string baseName = root.GetFullUrl();

                //if (w != null)
                //{
                //    infoList.Add(new BlogInfo()
                //     {
                //         blogid = w.Name,
                //         blogName = w.Title,
                //         url = w.GetFullUrl(),
                //         isAdmin = true,
                //         xmlrpc = baseName + ("/xmlrpc.metaweblog")
                //     });
                //}

                //if (root.Owner.Equals(username, StringComparison.OrdinalIgnoreCase))
                //{
                //    infoList.Add(new BlogInfo()
                //    {
                //        blogid = root.Name,
                //        blogName = root.Title,
                //        url = root.GetFullUrl(),
                //        isAdmin = true,
                //        xmlrpc = baseName + ("/xmlrpc.metaweblog")
                //    });
                //}

                return infoList.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        UserInfo IBlogger.GetUserInfo(string key, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                var profile = System.Web.Profile.ProfileBase.Create(username);
                profile.Initialize(username, true);
                UserInfo info = new UserInfo()
                {
                    userid = username,
                    email = profile["Email"] != null ? profile["Email"].ToString() : System.Web.Security.Membership.GetUser(username).Email,
                    firstname = "",
                    lastname = "",
                    nickname = profile["DisplayName"] != null ? profile["DisplayName"] as string : username,
                    url = profile["WebSite"] != null ? profile["WebSite"] as string : ""
                };
                return info;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        #endregion

        #region IWordPressEditing members

        string[] IWordPress.GetTags(string blogid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                var count = 0;
                var tags = srv.GetTags(blogid, out count);
                return tags.Select(t => t.Name).ToArray();
            }

            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        #region not support

        int IWordPress.NewPage(string blogId, string username, string password, PageParam page, bool publish)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    //var web = WebSite.Open(blogId);
            //    var blog = OpenBlog(blogId);
            //    var parentID = int.Parse(page.wp_page_parent_id);
            //    if (parentID > 0)
            //        if (!web.IsPageExists(parentID)) parentID = 0;

            //    var _webpage = web.CreatePage(new WebPage
            //    {
            //        Title = page.title,
            //        Description = page.mt_excerpt,
            //        ParentID = parentID,
            //        Pos = int.Parse(page.wp_page_order),
            //        AllowAnonymous = true,
            //        ShowInMenu = true,
            //        Owner = username
            //    });
            //    var widget = _webpage.AddWidget("Shared\\SimpleHtml", "zone0", 0);
            //    widget.Apply(new { Text = page.description });
            //    return _webpage.ID;
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        bool IWordPress.EditPage(string blogId, string pageId, string username, string password, PageParam page, bool publish)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    var web = WebSite.Open(blogId);
            //    var webPage = web.GetPage(int.Parse(pageId));
            //    var widget = webPage.Widgets.FirstOrDefault(w => ((w.Action == "SimpleHtml") && (w.Controller == "Widget")));
            //    if (widget != null)
            //    {
            //        widget.Apply(new { Text = page.description });
            //        webPage.Title = page.title;
            //        webPage.Description = page.mt_excerpt;
            //        if ((webPage.ParentID != int.Parse(page.wp_page_parent_id)) || (webPage.Pos != int.Parse(page.wp_page_order)))
            //            webPage.Move(int.Parse(page.wp_page_parent_id), int.Parse(page.wp_page_order));
            //        webPage.Update();
            //    }
            //    else
            //        throw new XmlRpcFaultException(1, "Widget not found.The page could not be saved.");
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        bool IWordPress.DeletePage(string blogId, string pageId, string username, string password)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    var web = WebSite.Open(blogId);
            //    var page = web.GetPage(pageId);
            //    page.Delete();
            //    return true;
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        Page IWordPress.GetPage(string blogId, string pageId, string username, string password)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    var web = WebSite.Open(blogId);
            //    var webPage = web.GetPage(int.Parse(pageId));
            //    var page = PopuplatePage(webPage);
            //    page.wp_password = password;
            //    return page;
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        /// <summary>
        /// Get an array of all the pages on a blog. Just the minimum details, lighter than wp.getPages. 
        /// </summary>
        /// <param name="blogid">The relationship name of the message container being edited. It is MyBlog in Wave 11, which is the user’s blog.</param>
        /// <param name="username">The name of the user’s space.</param>
        /// <param name="password">The user’s secret word.</param>
        /// <returns></returns>
        [XmlRpcMethod("wp.getPageList")]
        PageInfo[] IWordPress.GetPageList(string blogId, string username, string password)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    var pages = new List<PageInfo>();
            //    var web = WebSite.Open(blogId);
            //    var webpages = web.GetAllPages();

            //    foreach (var p in webpages)
            //        pages.Add(new PageInfo()
            //        {
            //            page_id = p.ID,
            //            page_parent_id = p.ParentID,
            //            dateCreated = p.Created,
            //            page_title = p.Title
            //        });
            //    return pages.ToArray();
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        Page[] IWordPress.GetPages(string blogId, string username, string password)
        {
            throw XmlRpcExcpetionFactory.NotSupport();
            //if (ValidateUser(username, password))
            //{
            //    var pages = new List<Page>();
            //    var web = WebSite.Open(blogId);
            //    var webpages = web.GetAllPages();
            //    foreach (var p in webpages)
            //        pages.Add(PopuplatePage(p));
            //    return pages.ToArray();
            //}
            //throw XmlRpcExcpetionFactory.UserUnvalidated();
        }
        #endregion

        /// <summary>
        /// Retrieve page templates.
        /// </summary>
        /// <param name="blogid">The relationship name of the message container being edited. It is MyBlog in Wave 11, which is the user’s blog.</param>
        /// <param name="username">The name of the user’s space.</param>
        /// <param name="password">The user’s secret word.</param>
        /// <returns></returns>
        [XmlRpcMethod("wp.getPageTemplates")]
        PageTemplate[] IWordPress.GetPageTemplates(string blogId, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                var pages = new List<PageTemplate>();
                string[] templateFiles = System.IO.Directory.GetFiles(HttpContext.Current.Server.MapPath("~/Views/DynamicUI/Layouts"));
                foreach (var name in templateFiles)
                {
                    string filename = System.IO.Path.GetFileNameWithoutExtension(name);
                    pages.Add(new PageTemplate()
                    {
                        name = filename,
                        description = filename
                    });
                }
                return pages.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        BlogInfo[] IWordPress.GetUsesBlogs(string username, string password)
        {
            return ((IBlogger)this).GetUsersBlogs("", username, password);
        }

        int IWordPress.GetCommentCount(string blogId, string username, string password, string post_id)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(blogId);
                var _id = int.Parse(post_id);
                var post = srv.GetPost(_id);
                // blog.GetPost();

                if (post == null)
                    throw XmlRpcExcpetionFactory.PostNotFound();

                return post.Comments.Count;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        PageStatus IWordPress.GetPostStatusList(string blogId, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                return new PageStatus();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        CategoryInfo[] IWordPress.GetCategories(string blogId, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(blogId); // GetBlog(blogId);
                var cats = srv.GetCategories(blogId);
                // blog.GetAllCategories();
                var catID = srv.FindCategory(blogId).ID;

                var result = new List<CategoryInfo>();
                foreach (var cat in cats)
                    result.Add(PopuplateCategoryInfo(cat, catID));

                return result.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        int IWordPress.NewCategory(string blogId, string username, string password, CategoryParam category)
        {
            if (ValidateUser(username, password))
            {
                if ((string.IsNullOrEmpty(category.name)) && (string.IsNullOrEmpty(category.categoryName)))
                    throw XmlRpcExcpetionFactory.NullCategoryName();

                //var blog = OpenBlog(blogId); //GetBlog(blogId);

                var _defaultCategoryID = srv.FindCategory(blogId).ID;
                var _parentCategory=srv.FindCategory(category.parent_id <= 0 ? _defaultCategoryID : category.parent_id);
                var _name = string.IsNullOrEmpty(category.categoryName) ? category.name : category.categoryName;
                var cat = srv.UpdateCategory(new Category()
                {
                    ParentID =_parentCategory.ID ,
                    Title = _name,
                    LastPosted=new DateTime(1800,1,1),
                    Description = category.description,
                    Path = (_parentCategory.Path + "/" + TextUtility.Slug(_name)).ToLower()
                });

                return cat.ID;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        CategoryInfo[] IWordPress.GetSuggestCategories(string blogId, string username, string password, string category, int max_results)
        {

            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(blogId);
                var _defaultCategoryID = srv.FindCategory(blogId).ID;
                var cats = srv.GetSuggestCategories(category, max_results);
                return cats.Select(c => PopuplateCategoryInfo(c, _defaultCategoryID)).ToArray();
            }

            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        bool IWordPress.DeleteCategory(string blogId, string username, string password, int category_id)
        {
            if (ValidateUser(username, password))
            {
                //                var blog = OpenBlog(blogId);
                srv.DeleteCategory(category_id);
                return true;
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        MediaObjectInfo IWordPress.UploadFile(string blogId, string username, string password, MediaObject file)
        {
            return ((IMetaWeblog)this).NewMediaObject(blogId, username, password, file);
        }

        #endregion

        #region IMovableType members

        PostTitle[] IMovableType.GetRecentPostTitles(string blogid, string username, string password, int numberOfPosts)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(blogid);
                var total = 0;
                var posts = srv.GetRecentPosts(blogid, 0, numberOfPosts, out total);
                var titles = new List<PostTitle>();
                foreach (var post in posts)
                {
                    titles.Add(new PostTitle()
                    {
                        postid = post.ID.ToString(),
                        title = post.Title,
                        dateCreated = post.Posted,
                        userid = post.UserName
                    });
                }
                return titles.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        CategoryInfo[] IMovableType.GetCategoryList(string postid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                return ((IMovableType)this).GetPostCategories(postid, username, password);
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();

        }

        CategoryInfo[] IMovableType.GetPostCategories(string postid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                //var blog = OpenBlog(username);
                int id = int.Parse(postid);
                var post = srv.GetPost(id);
                var primary = post.Category;
                var categories = srv.GetPostCategories(id); //.GetCategories();
                var result = new List<CategoryInfo>();
                var primaryCat = PopuplateCategoryInfo(primary, primary.ID);
                primaryCat.isPrimary = true;
                result.Add(primaryCat);

                foreach (var cat in categories)
                    result.Add(PopuplateCategoryInfo(cat, -1));

                return result.ToArray();
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        bool IMovableType.SetPostCategories(string postid, string username, string password, CategoryParam[] categories)
        {
            if (ValidateUser(username, password))
            {
                try
                {
                    //var blog = OpenBlog(username);
                    var post = srv.GetPost(int.Parse(postid));
                    if ((categories == null) || (categories.Length == 0))
                        post.Categories = "";
                    else
                    {
                        post.Categories = string.Join(",", categories.Where(c => c.isPrimary == false).Select(c => c.categoryId).ToArray());
                        var primary = categories.FirstOrDefault(c => c.isPrimary);
                        if (primary.categoryId != null)
                        {
                            var pID = int.Parse(primary.categoryId);
                            if (post.CategoryID != pID)
                                srv.MovePost(post.ID, 0, pID);
                            //               post.Move(pID);
                        }
                        else
                        {
                            post.Categories = string.Join(",", categories.Where(c => c.categoryId != post.CategoryID.ToString()).Select(c => c.categoryId).ToArray());
                        }
                    }
                    srv.EditPost(post);

                    //post.Update();
                    //_pubContext.Articles.Update(post);
                    //_pubContext.SaveChanges();
                    return true;
                }
                catch (Exception e)
                {
                    throw new XmlRpcFaultException(500, e.Message);
                }
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        string[] IMovableType.SupportedMethods()
        {
            throw XmlRpcExcpetionFactory.NotSupport();
        }

        Ping[] IMovableType.GetTrackbackPings(string postid)
        {
            try
            {
                var post = srv.GetPost(int.Parse(postid));

                var pings = new List<Ping>();
                if (post == null)
                    throw XmlRpcExcpetionFactory.PostNotFound();

                var comments = post.Comments;

                if (comments.Count() > 0)
                {
                    foreach (var comment in comments)
                    {
                        if (comment.IsTrackback)
                        {
                            pings.Add(new Ping()
                            {
                                pingTitle = comment.Title,
                                pingIP = comment.IP,
                                pingUrl = comment.WebSite
                            });
                        }
                    }
                }
                return pings.ToArray();
            }
            catch (Exception e)
            {
                throw new XmlRpcFaultException(500, e.Message);
            }
        }

        bool IMovableType.PublishPost(string postid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                try
                {
                    var post = srv.GetPost(int.Parse(postid));

                    if (!post.IsPublished)
                    {
                        post.IsPublished = true;
                        post.LastModified = DateTime.UtcNow;
                        srv.EditPost(post);
                        //_pubContext.Articles.Update(post);
                        //_pubContext.SaveChanges();
                        return true;
                    }
                    return false;
                }
                catch (Exception e)
                {
                    throw new XmlRpcFaultException(500, e.Message);
                }
            }
            throw XmlRpcExcpetionFactory.UserUnvalidated();
        }

        #endregion
    }
}